home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -in_the_mag- / multitasking / fixgetmsg / fixgetmsg.doc < prev    next >
Text File  |  2000-03-09  |  3KB  |  52 lines

  1.  
  2. Description:
  3.  
  4. FixGetMsg is a patch to get around a problem that occurs when the Exec
  5. GetMsg() is called in a tight loop on a fast CPU such as the 68060.  This
  6. shouldn't happen in well-written code, but dumb code that uses polling of
  7. GetMsg() rather than waiting for a signal may do this.  The result can be a
  8. complete lockup of the system due to interrupt exclusion.
  9.  
  10. Usage:
  11.  
  12. Running FixGetMsg installs the patch and exits, provided that GetMsg() is
  13. not already patched and has the expected first instruction.  The patch
  14. requires 32 bytes of RAM.  FixGetMsg can be installed in User-Startup.
  15.  
  16. Details of the Problem and the Fix:
  17.  
  18. The problem is that GetMsg() disables interrupts in order to stabilize the
  19. port queue, which is ordinarily reasonable, but when it is called in a
  20. tight loop the duration of the time that interrupts are enabled is rather
  21. short.  Due to pipelining, by the time the enable actually gets turned on
  22. in the hardware, the code may already be executing in the disabled section.
  23. This is a possible race on any processor (even a 7MHz 68000), but is
  24. avoided by having the interrupt stubs check the enable before dispatching
  25. to the handler.  In this tight looping case however, the interrupt routines
  26. may find the interrupts disabled at the time of the interrupt *every time
  27. around the loop*, thus locking up the system.
  28.  
  29. FixGetMsg patches GetMsg() to avoid this problem by checking the emptiness
  30. of the queue before disabling interrupts, which can be done safely.  This
  31. slightly increases the overhead in the normal (nonempty) case, but avoids
  32. the disabling altogether when the queue is empty.  The patch includes a
  33. counter for the cases where the queue was empty, to get an idea of how
  34. often this happens.  The counter is the longword immediately preceding the
  35. patched version of GetMsg(), and can be inspected with a debugger.  The
  36. count should be very large after running LoopGetMsg.
  37.  
  38. The program LoopGetMSg is used to test this.  It calls GetMsg() on an empty
  39. dummy MsgPort 10 million times and exits.  On my 060/50 system without the
  40. patch, this locks the system for ~50 seconds.  With the patch, the system
  41. continues normally and the program exits in about 4 seconds.
  42.  
  43. For some reason that I don't really understand, disabling the write buffer
  44. with cpu060 doesn't avoid the problem in the unpatched system, but
  45. disabling Superscalar mode does.  Perhaps the latter only helps by slowing
  46. down the CPU, rather than by its logical effect.
  47.  
  48.  
  49.                     Frederick H. G. Wright II
  50.                     fw@well.com
  51.                     13-Jan-1999
  52.